package net.yegong;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.OutputStream;

import net.yegong.matrix.Matrix;
import net.yegong.matrix.RowVector;
import net.yegong.matrix.Transformer;

public class Unzip {

	public static void unzip(ObjectInputStream is, OutputStream os) throws IOException {
		int factor;
		int bands = is.readInt();
		int rows = is.readInt();
		int cols = is.readInt();
		Logger.log("Bands: %d\nRows: %d\nCols: %d", bands, rows, cols);
		while (0 != (factor = is.readInt())) {
			Matrix eig = new Matrix(bands, factor);
			RowVector std = new RowVector(bands);
			RowVector mean = new RowVector(bands);
			for (int i = 0; i < eig.getRowsCount(); ++i) {
				for (int j = 0; j < eig.getColumnsCount(); ++j) {
					eig.set(i, j, is.readFloat());
				}
			}
			for (int i = 0; i < bands; ++i) {
				std.set(i, is.readFloat());
			}
			for (int i = 0; i < bands; ++i) {
				mean.set(i, is.readFloat());
			}
			RowVector max = new RowVector(factor);
			RowVector min = new RowVector(factor);
			for (int i = 0; i < factor; ++i) {
				max.set(i, is.readFloat());
			}
			for (int i = 0; i < factor; ++i) {
				min.set(i, is.readFloat());
			}
			int nRows = is.readInt();
			float[] raw = new float[nRows * factor];

			for (int i = 0; i < raw.length; ++i) {
				int value = is.read();
				raw[i] = value;
			}
			Matrix a1 = new Matrix(raw, nRows, factor, Matrix.FORTRAN);

			Transformer.multiplyEachRow(a1, max.minus(min).multiply(1.0f / 255).toRowVector());
			Transformer.addEachRow(a1, min);

			Matrix b2 = a1.leftMultiply(eig.transpose());
			Transformer.multiplyEachRow(b2, std);
			Transformer.addEachRow(b2, mean);

			for (float f : b2.getRowMajorArrayCopy()) {
				int value = Math.round(f);
				value = Math.min(127, value);
				value = Math.max(-128, value);
				os.write(value);
			}
		}
		os.flush();
	}

}
